# Written by koya
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

import maths,math

class grid_node_obj( object ):
    def __init__( self ):
        self.position = 0.0
        self.velocity = 0.0
        self.vertex = maths.vector_obj( 0.0, 0.0, 0.0 )
        self.normal = maths.vector_obj( 0.0, 1.0, 0.0 )

class water_ripple_obj ( object ):

    def __init__( self, size_width, size_height, viscosity ):

        self.grid_size_width = size_width
        self.grid_size_height = size_height
        self.viscosity = viscosity

        self.water_node = []

        self.average_wh = ( self.grid_size_width + self.grid_size_height )*0.5

        for i in xrange( (self.grid_size_width + 1) * (self.grid_size_height + 1) + 1 ):
            self.water_node.append( grid_node_obj() )
        
    def create_raindrop( self, pos_x, pos_y, power ):

        self.water_node[ pos_x + pos_y * self.grid_size_width ].velocity = power


    def draw_water( self ):

        for i in xrange( 2, self.grid_size_width - 1 ):
            
            for j in xrange( 2, self.grid_size_height - 1 ):

                index_ij = i + j * self.grid_size_width 
                index_i0 = index_ij - 1
                index_i1 = index_ij + 1
                index_j0 = index_ij - self.grid_size_width
                index_j1 = index_ij + self.grid_size_width
              

                self.water_node[ index_ij ].velocity =\
                          float( self.water_node[ index_ij ].velocity +\
                          (self.water_node[ index_ij ].position -\
						  ( 4 * (self.water_node[ index_i0 ].position +\
                          self.water_node[ index_i1 ].position +\
                          self.water_node[ index_j0 ].position +\
                          self.water_node[ index_j1 ].position)+\
                          self.water_node[ index_j0 - 1 ].position +\
                          self.water_node[ index_j0 + 1 ].position +\
                          self.water_node[ index_j1 - 1 ].position +\
                          self.water_node[ index_j1 + 1 ].position) * 0.04) )

        for i in xrange( 2, self.grid_size_width - 1 ):
            
            for j in xrange( 2, self.grid_size_height - 1 ):

                index = i + j * self.grid_size_width

                self.water_node[ index ].position -= self.water_node[ index ].velocity
                self.water_node[ index ].velocity *= self.viscosity

        pos_y = 1.0/(self.average_wh * 15.0 + 7.0)
        pos_z0 = 1.0 / self.grid_size_height * 392.0
        pos_z = ( - self.grid_size_height * 0.5 )*pos_z0
        
        for i in xrange( self.grid_size_width + 1 ):

            pos_x = ( i - self.grid_size_width * 0.5 )/ self.grid_size_width * 392.0
            
            for j in xrange( self.grid_size_height + 1 ):

                index =  i + j * self.grid_size_width 

                self.water_node[ index ].vertex.x = pos_x
                self.water_node[ index ].vertex.y = ( self.water_node[ index ].position / 1024.0)*pos_y
                self.water_node[ index ].vertex.z = j * pos_z0 + pos_z

        for i in xrange( self.grid_size_width + 1 ):
            
            for j in xrange( self.grid_size_height + 1 ):

                index_ij = i + j * self.grid_size_width

                if i > 0 and j > 0 and i < self.grid_size_width and j < self.grid_size_height:

                    self.water_node[ index_ij ].normal.x =\
                          self.water_node[ index_ij + 1 ].position -\
                          self.water_node[ index_ij - 1 ].position

                    self.water_node[ index_ij ].normal.y = -2048

                    self.water_node[ index_ij ].normal.z =\
                          self.water_node[ index_ij + self.grid_size_width ].position -\
                          self.water_node[ index_ij - self.grid_size_width ].position

                    x = self.water_node[ index_ij ].normal.x
                    y = self.water_node[ index_ij ].normal.y
                    z = self.water_node[ index_ij ].normal.z

                    length = float( math.sqrt( x*x + y*y + z*z ) )

                    if length != 0:

                        self.water_node[ index_ij ].normal.x /= length
                        self.water_node[ index_ij ].normal.y /= length
                        self.water_node[ index_ij ].normal.z /= length
                else:

                    self.water_node[ index_ij ].normal.x = 0
                    self.water_node[ index_ij ].normal.y = 1
                    self.water_node[ index_ij ].normal.z = 0

        
        for j in xrange( self.grid_size_width ):

            glBegin(GL_QUAD_STRIP)

            for i in xrange( self.grid_size_height + 1 ):
                
                index_ij = i+j*self.grid_size_width
                index_j1 = index_ij + self.grid_size_width
               
                glNormal3f( self.water_node[index_j1].normal.x,self.water_node[index_j1].normal.y,self.water_node[index_j1].normal.z )

		glVertex3f( self.water_node[index_j1].vertex.x,self.water_node[index_j1].vertex.y,self.water_node[index_j1].vertex.z )			
		glNormal3f( self.water_node[index_ij].normal.x,self.water_node[index_ij].normal.y,self.water_node[index_ij].normal.z )
		glVertex3f( self.water_node[index_ij].vertex.x,self.water_node[index_ij].vertex.y,self.water_node[index_ij].vertex.z )

            glEnd()
        
               


        

